Skip to main content

core/stdarch/crates/core_arch/src/x86/
mod.rs

1//! `x86` and `x86_64` intrinsics.
2
3use crate::mem::transmute;
4
5#[macro_use]
6mod macros;
7
8types! {
9    #![stable(feature = "simd_x86", since = "1.27.0")]
10
11    /// 128-bit wide integer vector type, x86-specific
12    ///
13    /// This type is the same as the `__m128i` type defined by Intel,
14    /// representing a 128-bit SIMD register. Usage of this type typically
15    /// corresponds to the `sse` and up target features for x86/x86_64.
16    ///
17    /// Internally this type may be viewed as:
18    ///
19    /// * `i8x16` - sixteen `i8` variables packed together
20    /// * `i16x8` - eight `i16` variables packed together
21    /// * `i32x4` - four `i32` variables packed together
22    /// * `i64x2` - two `i64` variables packed together
23    ///
24    /// (as well as unsigned versions). Each intrinsic may interpret the
25    /// internal bits differently, check the documentation of the intrinsic
26    /// to see how it's being used.
27    ///
28    /// The in-memory representation of this type is the same as the one of an
29    /// equivalent array (i.e. the in-memory order of elements is the same, and
30    /// there is no padding); however, the alignment is different and equal to
31    /// the size of the type. Note that the ABI for function calls may *not* be
32    /// the same.
33    ///
34    /// Note that this means that an instance of `__m128i` typically just means
35    /// a "bag of bits" which is left up to interpretation at the point of use.
36    ///
37    /// Most intrinsics using `__m128i` are prefixed with `_mm_` and the
38    /// integer types tend to correspond to suffixes like "epi8" or "epi32".
39    ///
40    /// # Examples
41    ///
42    /// ```
43    /// # #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] {
44    /// #[cfg(target_arch = "x86")]
45    /// use std::arch::x86::*;
46    /// #[cfg(target_arch = "x86_64")]
47    /// use std::arch::x86_64::*;
48    ///
49    /// # #[target_feature(enable = "sse2")]
50    /// # #[allow(unused_unsafe)] // temporary, to unstick CI
51    /// # unsafe fn foo() { unsafe {
52    /// let all_bytes_zero = _mm_setzero_si128();
53    /// let all_bytes_one = _mm_set1_epi8(1);
54    /// let four_i32 = _mm_set_epi32(1, 2, 3, 4);
55    /// # }}
56    /// # if is_x86_feature_detected!("sse2") { unsafe { foo() } }
57    /// # }
58    /// ```
59    #[doc(cfg(any(target_arch = "x86", target_arch = "x86_64")))]
60    pub struct __m128i(2 x i64);
61
62    /// 128-bit wide set of four `f32` types, x86-specific
63    ///
64    /// This type is the same as the `__m128` type defined by Intel,
65    /// representing a 128-bit SIMD register which internally is consisted of
66    /// four packed `f32` instances. Usage of this type typically corresponds
67    /// to the `sse` and up target features for x86/x86_64.
68    ///
69    /// Note that unlike `__m128i`, the integer version of the 128-bit
70    /// registers, this `__m128` type has *one* interpretation. Each instance
71    /// of `__m128` always corresponds to `f32x4`, or four `f32` types packed
72    /// together.
73    ///
74    /// The in-memory representation of this type is the same as the one of an
75    /// equivalent array (i.e. the in-memory order of elements is the same, and
76    /// there is no padding); however, the alignment is different and equal to
77    /// the size of the type. Note that the ABI for function calls may *not* be
78    /// the same.
79    ///
80    /// Most intrinsics using `__m128` are prefixed with `_mm_` and are
81    /// suffixed with "ps" (or otherwise contain "ps"). Not to be confused with
82    /// "pd" which is used for `__m128d`.
83    ///
84    /// # Examples
85    ///
86    /// ```
87    /// # #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] {
88    /// #[cfg(target_arch = "x86")]
89    /// use std::arch::x86::*;
90    /// #[cfg(target_arch = "x86_64")]
91    /// use std::arch::x86_64::*;
92    ///
93    /// # #[target_feature(enable = "sse")]
94    /// # #[allow(unused_unsafe)] // temporary, to unstick CI
95    /// # unsafe fn foo() { unsafe {
96    /// let four_zeros = _mm_setzero_ps();
97    /// let four_ones = _mm_set1_ps(1.0);
98    /// let four_floats = _mm_set_ps(1.0, 2.0, 3.0, 4.0);
99    /// # }}
100    /// # if is_x86_feature_detected!("sse") { unsafe { foo() } }
101    /// # }
102    /// ```
103    #[doc(cfg(any(target_arch = "x86", target_arch = "x86_64")))]
104    pub struct __m128(4 x f32);
105
106    /// 128-bit wide set of two `f64` types, x86-specific
107    ///
108    /// This type is the same as the `__m128d` type defined by Intel,
109    /// representing a 128-bit SIMD register which internally is consisted of
110    /// two packed `f64` instances. Usage of this type typically corresponds
111    /// to the `sse` and up target features for x86/x86_64.
112    ///
113    /// Note that unlike `__m128i`, the integer version of the 128-bit
114    /// registers, this `__m128d` type has *one* interpretation. Each instance
115    /// of `__m128d` always corresponds to `f64x2`, or two `f64` types packed
116    /// together.
117    ///
118    /// The in-memory representation of this type is the same as the one of an
119    /// equivalent array (i.e. the in-memory order of elements is the same, and
120    /// there is no padding); however, the alignment is different and equal to
121    /// the size of the type. Note that the ABI for function calls may *not* be
122    /// the same.
123    ///
124    /// Most intrinsics using `__m128d` are prefixed with `_mm_` and are
125    /// suffixed with "pd" (or otherwise contain "pd"). Not to be confused with
126    /// "ps" which is used for `__m128`.
127    ///
128    /// # Examples
129    ///
130    /// ```
131    /// # #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] {
132    /// #[cfg(target_arch = "x86")]
133    /// use std::arch::x86::*;
134    /// #[cfg(target_arch = "x86_64")]
135    /// use std::arch::x86_64::*;
136    ///
137    /// # #[target_feature(enable = "sse2")]
138    /// # #[allow(unused_unsafe)] // temporary, to unstick CI
139    /// # unsafe fn foo() { unsafe {
140    /// let two_zeros = _mm_setzero_pd();
141    /// let two_ones = _mm_set1_pd(1.0);
142    /// let two_floats = _mm_set_pd(1.0, 2.0);
143    /// # }}
144    /// # if is_x86_feature_detected!("sse2") { unsafe { foo() } }
145    /// # }
146    /// ```
147    #[doc(cfg(any(target_arch = "x86", target_arch = "x86_64")))]
148    pub struct __m128d(2 x f64);
149
150    /// 256-bit wide integer vector type, x86-specific
151    ///
152    /// This type is the same as the `__m256i` type defined by Intel,
153    /// representing a 256-bit SIMD register. Usage of this type typically
154    /// corresponds to the `avx` and up target features for x86/x86_64.
155    ///
156    /// Internally this type may be viewed as:
157    ///
158    /// * `i8x32` - thirty two `i8` variables packed together
159    /// * `i16x16` - sixteen `i16` variables packed together
160    /// * `i32x8` - eight `i32` variables packed together
161    /// * `i64x4` - four `i64` variables packed together
162    ///
163    /// (as well as unsigned versions). Each intrinsic may interpret the
164    /// internal bits differently, check the documentation of the intrinsic
165    /// to see how it's being used.
166    ///
167    /// The in-memory representation of this type is the same as the one of an
168    /// equivalent array (i.e. the in-memory order of elements is the same, and
169    /// there is no padding); however, the alignment is different and equal to
170    /// the size of the type. Note that the ABI for function calls may *not* be
171    /// the same.
172    ///
173    /// Note that this means that an instance of `__m256i` typically just means
174    /// a "bag of bits" which is left up to interpretation at the point of use.
175    ///
176    /// # Examples
177    ///
178    /// ```
179    /// # #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] {
180    /// #[cfg(target_arch = "x86")]
181    /// use std::arch::x86::*;
182    /// #[cfg(target_arch = "x86_64")]
183    /// use std::arch::x86_64::*;
184    ///
185    /// # #[target_feature(enable = "avx")]
186    /// # #[allow(unused_unsafe)] // temporary, to unstick CI
187    /// # unsafe fn foo() { unsafe {
188    /// let all_bytes_zero = _mm256_setzero_si256();
189    /// let all_bytes_one = _mm256_set1_epi8(1);
190    /// let eight_i32 = _mm256_set_epi32(1, 2, 3, 4, 5, 6, 7, 8);
191    /// # }}
192    /// # if is_x86_feature_detected!("avx") { unsafe { foo() } }
193    /// # }
194    /// ```
195    #[doc(cfg(any(target_arch = "x86", target_arch = "x86_64")))]
196    pub struct __m256i(4 x i64);
197
198    /// 256-bit wide set of eight `f32` types, x86-specific
199    ///
200    /// This type is the same as the `__m256` type defined by Intel,
201    /// representing a 256-bit SIMD register which internally is consisted of
202    /// eight packed `f32` instances. Usage of this type typically corresponds
203    /// to the `avx` and up target features for x86/x86_64.
204    ///
205    /// Note that unlike `__m256i`, the integer version of the 256-bit
206    /// registers, this `__m256` type has *one* interpretation. Each instance
207    /// of `__m256` always corresponds to `f32x8`, or eight `f32` types packed
208    /// together.
209    ///
210    /// The in-memory representation of this type is the same as the one of an
211    /// equivalent array (i.e. the in-memory order of elements is the same, and
212    /// there is no padding  between two consecutive elements); however, the
213    /// alignment is different and equal to the size of the type. Note that the
214    /// ABI for function calls may *not* be the same.
215    ///
216    /// Most intrinsics using `__m256` are prefixed with `_mm256_` and are
217    /// suffixed with "ps" (or otherwise contain "ps"). Not to be confused with
218    /// "pd" which is used for `__m256d`.
219    ///
220    /// # Examples
221    ///
222    /// ```
223    /// # #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] {
224    /// #[cfg(target_arch = "x86")]
225    /// use std::arch::x86::*;
226    /// #[cfg(target_arch = "x86_64")]
227    /// use std::arch::x86_64::*;
228    ///
229    /// # #[target_feature(enable = "avx")]
230    /// # #[allow(unused_unsafe)] // temporary, to unstick CI
231    /// # unsafe fn foo() { unsafe {
232    /// let eight_zeros = _mm256_setzero_ps();
233    /// let eight_ones = _mm256_set1_ps(1.0);
234    /// let eight_floats = _mm256_set_ps(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0);
235    /// # }}
236    /// # if is_x86_feature_detected!("avx") { unsafe { foo() } }
237    /// # }
238    /// ```
239    #[doc(cfg(any(target_arch = "x86", target_arch = "x86_64")))]
240    pub struct __m256(8 x f32);
241
242    /// 256-bit wide set of four `f64` types, x86-specific
243    ///
244    /// This type is the same as the `__m256d` type defined by Intel,
245    /// representing a 256-bit SIMD register which internally is consisted of
246    /// four packed `f64` instances. Usage of this type typically corresponds
247    /// to the `avx` and up target features for x86/x86_64.
248    ///
249    /// Note that unlike `__m256i`, the integer version of the 256-bit
250    /// registers, this `__m256d` type has *one* interpretation. Each instance
251    /// of `__m256d` always corresponds to `f64x4`, or four `f64` types packed
252    /// together.
253    ///
254    /// The in-memory representation of this type is the same as the one of an
255    /// equivalent array (i.e. the in-memory order of elements is the same, and
256    /// there is no padding); however, the alignment is different and equal to
257    /// the size of the type. Note that the ABI for function calls may *not* be
258    /// the same.
259    ///
260    /// Most intrinsics using `__m256d` are prefixed with `_mm256_` and are
261    /// suffixed with "pd" (or otherwise contain "pd"). Not to be confused with
262    /// "ps" which is used for `__m256`.
263    ///
264    /// # Examples
265    ///
266    /// ```
267    /// # #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] {
268    /// #[cfg(target_arch = "x86")]
269    /// use std::arch::x86::*;
270    /// #[cfg(target_arch = "x86_64")]
271    /// use std::arch::x86_64::*;
272    ///
273    /// # #[target_feature(enable = "avx")]
274    /// # #[allow(unused_unsafe)] // temporary, to unstick CI
275    /// # unsafe fn foo() { unsafe {
276    /// let four_zeros = _mm256_setzero_pd();
277    /// let four_ones = _mm256_set1_pd(1.0);
278    /// let four_floats = _mm256_set_pd(1.0, 2.0, 3.0, 4.0);
279    /// # }}
280    /// # if is_x86_feature_detected!("avx") { unsafe { foo() } }
281    /// # }
282    /// ```
283    #[doc(cfg(any(target_arch = "x86", target_arch = "x86_64")))]
284    pub struct __m256d(4 x f64);
285}
286
287types! {
288    #![stable(feature = "simd_avx512_types", since = "1.72.0")]
289
290    /// 512-bit wide integer vector type, x86-specific
291    ///
292    /// This type is the same as the `__m512i` type defined by Intel,
293    /// representing a 512-bit SIMD register. Usage of this type typically
294    /// corresponds to the `avx512*` and up target features for x86/x86_64.
295    ///
296    /// Internally this type may be viewed as:
297    ///
298    /// * `i8x64` - sixty-four `i8` variables packed together
299    /// * `i16x32` - thirty-two `i16` variables packed together
300    /// * `i32x16` - sixteen `i32` variables packed together
301    /// * `i64x8` - eight `i64` variables packed together
302    ///
303    /// (as well as unsigned versions). Each intrinsic may interpret the
304    /// internal bits differently, check the documentation of the intrinsic
305    /// to see how it's being used.
306    ///
307    /// The in-memory representation of this type is the same as the one of an
308    /// equivalent array (i.e. the in-memory order of elements is the same, and
309    /// there is no padding); however, the alignment is different and equal to
310    /// the size of the type. Note that the ABI for function calls may *not* be
311    /// the same.
312    ///
313    /// Note that this means that an instance of `__m512i` typically just means
314    /// a "bag of bits" which is left up to interpretation at the point of use.
315    pub struct __m512i(8 x i64);
316
317    /// 512-bit wide set of sixteen `f32` types, x86-specific
318    ///
319    /// This type is the same as the `__m512` type defined by Intel,
320    /// representing a 512-bit SIMD register which internally is consisted of
321    /// eight packed `f32` instances. Usage of this type typically corresponds
322    /// to the `avx512*` and up target features for x86/x86_64.
323    ///
324    /// Note that unlike `__m512i`, the integer version of the 512-bit
325    /// registers, this `__m512` type has *one* interpretation. Each instance
326    /// of `__m512` always corresponds to `f32x16`, or sixteen `f32` types
327    /// packed together.
328    ///
329    /// The in-memory representation of this type is the same as the one of an
330    /// equivalent array (i.e. the in-memory order of elements is the same, and
331    /// there is no padding  between two consecutive elements); however, the
332    /// alignment is different and equal to the size of the type. Note that the
333    /// ABI for function calls may *not* be the same.
334    ///
335    /// Most intrinsics using `__m512` are prefixed with `_mm512_` and are
336    /// suffixed with "ps" (or otherwise contain "ps"). Not to be confused with
337    /// "pd" which is used for `__m512d`.
338    pub struct __m512(16 x f32);
339
340    /// 512-bit wide set of eight `f64` types, x86-specific
341    ///
342    /// This type is the same as the `__m512d` type defined by Intel,
343    /// representing a 512-bit SIMD register which internally is consisted of
344    /// eight packed `f64` instances. Usage of this type typically corresponds
345    /// to the `avx` and up target features for x86/x86_64.
346    ///
347    /// Note that unlike `__m512i`, the integer version of the 512-bit
348    /// registers, this `__m512d` type has *one* interpretation. Each instance
349    /// of `__m512d` always corresponds to `f64x8`, or eight `f64` types packed
350    /// together.
351    ///
352    /// The in-memory representation of this type is the same as the one of an
353    /// equivalent array (i.e. the in-memory order of elements is the same, and
354    /// there is no padding  between two consecutive elements); however, the
355    /// alignment is different and equal to the size of the type. Note that the
356    /// ABI for function calls may *not* be the same.
357    ///
358    /// Most intrinsics using `__m512d` are prefixed with `_mm512_` and are
359    /// suffixed with "pd" (or otherwise contain "pd"). Not to be confused with
360    /// "ps" which is used for `__m512`.
361    pub struct __m512d(8 x f64);
362}
363
364types! {
365    #![stable(feature = "stdarch_x86_avx512", since = "1.89")]
366
367    /// 128-bit wide set of eight `u16` types, x86-specific
368    ///
369    /// This type is representing a 128-bit SIMD register which internally is consisted of
370    /// eight packed `u16` instances. Its purpose is for bf16 related intrinsic
371    /// implementations.
372    ///
373    /// The in-memory representation of this type is the same as the one of an
374    /// equivalent array (i.e. the in-memory order of elements is the same, and
375    /// there is no padding); however, the alignment is different and equal to
376    /// the size of the type. Note that the ABI for function calls may *not* be
377    /// the same.
378    pub struct __m128bh(8 x u16);
379
380    /// 256-bit wide set of 16 `u16` types, x86-specific
381    ///
382    /// This type is the same as the `__m256bh` type defined by Intel,
383    /// representing a 256-bit SIMD register which internally is consisted of
384    /// 16 packed `u16` instances. Its purpose is for bf16 related intrinsic
385    /// implementations.
386    ///
387    /// The in-memory representation of this type is the same as the one of an
388    /// equivalent array (i.e. the in-memory order of elements is the same, and
389    /// there is no padding); however, the alignment is different and equal to
390    /// the size of the type. Note that the ABI for function calls may *not* be
391    /// the same.
392    pub struct __m256bh(16 x u16);
393
394    /// 512-bit wide set of 32 `u16` types, x86-specific
395    ///
396    /// This type is the same as the `__m512bh` type defined by Intel,
397    /// representing a 512-bit SIMD register which internally is consisted of
398    /// 32 packed `u16` instances. Its purpose is for bf16 related intrinsic
399    /// implementations.
400    ///
401    /// The in-memory representation of this type is the same as the one of an
402    /// equivalent array (i.e. the in-memory order of elements is the same, and
403    /// there is no padding); however, the alignment is different and equal to
404    /// the size of the type. Note that the ABI for function calls may *not* be
405    /// the same.
406    pub struct __m512bh(32 x u16);
407}
408
409types! {
410    #![stable(feature = "stdarch_x86_avx512fp16", since = "1.94.0")]
411
412    /// 128-bit wide set of 8 `f16` types, x86-specific
413    ///
414    /// This type is the same as the `__m128h` type defined by Intel,
415    /// representing a 128-bit SIMD register which internally is consisted of
416    /// 8 packed `f16` instances. its purpose is for f16 related intrinsic
417    /// implementations.
418    ///
419    /// The in-memory representation of this type is the same as the one of an
420    /// equivalent array (i.e. the in-memory order of elements is the same, and
421    /// there is no padding); however, the alignment is different and equal to
422    /// the size of the type. Note that the ABI for function calls may *not* be
423    /// the same.
424    pub struct __m128h(8 x f16);
425
426    /// 256-bit wide set of 16 `f16` types, x86-specific
427    ///
428    /// This type is the same as the `__m256h` type defined by Intel,
429    /// representing a 256-bit SIMD register which internally is consisted of
430    /// 16 packed `f16` instances. its purpose is for f16 related intrinsic
431    /// implementations.
432    ///
433    /// The in-memory representation of this type is the same as the one of an
434    /// equivalent array (i.e. the in-memory order of elements is the same, and
435    /// there is no padding); however, the alignment is different and equal to
436    /// the size of the type. Note that the ABI for function calls may *not* be
437    /// the same.
438    pub struct __m256h(16 x f16);
439
440    /// 512-bit wide set of 32 `f16` types, x86-specific
441    ///
442    /// This type is the same as the `__m512h` type defined by Intel,
443    /// representing a 512-bit SIMD register which internally is consisted of
444    /// 32 packed `f16` instances. its purpose is for f16 related intrinsic
445    /// implementations.
446    ///
447    /// The in-memory representation of this type is the same as the one of an
448    /// equivalent array (i.e. the in-memory order of elements is the same, and
449    /// there is no padding); however, the alignment is different and equal to
450    /// the size of the type. Note that the ABI for function calls may *not* be
451    /// the same.
452    pub struct __m512h(32 x f16);
453}
454
455/// The BFloat16 type used in AVX-512 intrinsics.
456#[repr(transparent)]
457#[derive(Copy, Clone, Debug)]
458#[allow(non_camel_case_types)]
459#[unstable(feature = "stdarch_x86_avx512_bf16", issue = "127356")]
460pub struct bf16(u16);
461
462impl bf16 {
463    /// Raw transmutation from `u16`
464    #[inline]
465    #[must_use]
466    #[unstable(feature = "stdarch_x86_avx512_bf16", issue = "127356")]
467    pub const fn from_bits(bits: u16) -> bf16 {
468        bf16(bits)
469    }
470
471    /// Raw transmutation to `u16`
472    #[inline]
473    #[must_use = "this returns the result of the operation, without modifying the original"]
474    #[unstable(feature = "stdarch_x86_avx512_bf16", issue = "127356")]
475    pub const fn to_bits(self) -> u16 {
476        self.0
477    }
478}
479
480/// The `__mmask64` type used in AVX-512 intrinsics, a 64-bit integer
481#[allow(non_camel_case_types)]
482#[stable(feature = "stdarch_x86_avx512", since = "1.89")]
483pub type __mmask64 = u64;
484
485/// The `__mmask32` type used in AVX-512 intrinsics, a 32-bit integer
486#[allow(non_camel_case_types)]
487#[stable(feature = "stdarch_x86_avx512", since = "1.89")]
488pub type __mmask32 = u32;
489
490/// The `__mmask16` type used in AVX-512 intrinsics, a 16-bit integer
491#[allow(non_camel_case_types)]
492#[stable(feature = "stdarch_x86_avx512", since = "1.89")]
493pub type __mmask16 = u16;
494
495/// The `__mmask8` type used in AVX-512 intrinsics, a 8-bit integer
496#[allow(non_camel_case_types)]
497#[stable(feature = "stdarch_x86_avx512", since = "1.89")]
498pub type __mmask8 = u8;
499
500/// The `_MM_CMPINT_ENUM` type used to specify comparison operations in AVX-512 intrinsics.
501#[allow(non_camel_case_types)]
502#[stable(feature = "stdarch_x86_avx512", since = "1.89")]
503pub type _MM_CMPINT_ENUM = i32;
504
505/// The `MM_MANTISSA_NORM_ENUM` type used to specify mantissa normalized operations in AVX-512 intrinsics.
506#[allow(non_camel_case_types)]
507#[stable(feature = "stdarch_x86_avx512", since = "1.89")]
508pub type _MM_MANTISSA_NORM_ENUM = i32;
509
510/// The `MM_MANTISSA_SIGN_ENUM` type used to specify mantissa signed operations in AVX-512 intrinsics.
511#[allow(non_camel_case_types)]
512#[stable(feature = "stdarch_x86_avx512", since = "1.89")]
513pub type _MM_MANTISSA_SIGN_ENUM = i32;
514
515/// The `MM_PERM_ENUM` type used to specify shuffle operations in AVX-512 intrinsics.
516#[allow(non_camel_case_types)]
517#[stable(feature = "stdarch_x86_avx512", since = "1.89")]
518pub type _MM_PERM_ENUM = i32;
519
520#[cfg(test)]
521mod test;
522#[cfg(test)]
523pub use self::test::*;
524
525macro_rules! as_transmute {
526    ($from:ty => $as_from:ident, $($as_to:ident -> $to:ident),* $(,)?) => {
527        impl $from {$(
528            #[inline]
529            pub(crate) const fn $as_to(self) -> crate::core_arch::simd::$to {
530                unsafe { transmute(self) }
531            }
532        )*}
533        $(
534            impl crate::core_arch::simd::$to {
535                #[inline]
536                pub(crate) const fn $as_from(self) -> $from {
537                    unsafe { transmute(self) }
538                }
539            }
540        )*
541    };
542}
543
544as_transmute!(__m128i =>
545    as_m128i,
546    as_u8x16 -> u8x16,
547    as_u16x8 -> u16x8,
548    as_u32x4 -> u32x4,
549    as_u64x2 -> u64x2,
550    as_i8x16 -> i8x16,
551    as_i16x8 -> i16x8,
552    as_i32x4 -> i32x4,
553    as_i64x2 -> i64x2,
554);
555as_transmute!(__m256i =>
556    as_m256i,
557    as_u8x32 -> u8x32,
558    as_u16x16 -> u16x16,
559    as_u32x8 -> u32x8,
560    as_u64x4 -> u64x4,
561    as_i8x32 -> i8x32,
562    as_i16x16 -> i16x16,
563    as_i32x8 -> i32x8,
564    as_i64x4 -> i64x4,
565);
566as_transmute!(__m512i =>
567    as_m512i,
568    as_u8x64 -> u8x64,
569    as_u16x32 -> u16x32,
570    as_u32x16 -> u32x16,
571    as_u64x8 -> u64x8,
572    as_i8x64 -> i8x64,
573    as_i16x32 -> i16x32,
574    as_i32x16 -> i32x16,
575    as_i64x8 -> i64x8,
576);
577
578as_transmute!(__m128 => as_m128, as_f32x4 -> f32x4);
579as_transmute!(__m128d => as_m128d, as_f64x2 -> f64x2);
580as_transmute!(__m256 => as_m256, as_f32x8 -> f32x8);
581as_transmute!(__m256d => as_m256d, as_f64x4 -> f64x4);
582as_transmute!(__m512 => as_m512, as_f32x16 -> f32x16);
583as_transmute!(__m512d => as_m512d, as_f64x8 -> f64x8);
584
585as_transmute!(__m128bh =>
586    as_m128bh,
587    as_u16x8 -> u16x8,
588    as_u32x4 -> u32x4,
589    as_i16x8 -> i16x8,
590    as_i32x4 -> i32x4,
591);
592as_transmute!(__m256bh =>
593    as_m256bh,
594    as_u16x16 -> u16x16,
595    as_u32x8 -> u32x8,
596    as_i16x16 -> i16x16,
597    as_i32x8 -> i32x8,
598);
599as_transmute!(__m512bh =>
600    as_m512bh,
601    as_u16x32 -> u16x32,
602    as_u32x16 -> u32x16,
603    as_i16x32 -> i16x32,
604    as_i32x16 -> i32x16,
605);
606
607as_transmute!(__m128h => as_m128h, as_f16x8 -> f16x8);
608as_transmute!(__m256h => as_m256h, as_f16x16 -> f16x16);
609as_transmute!(__m512h => as_m512h, as_f16x32 -> f16x32);
610
611mod eflags;
612#[stable(feature = "simd_x86", since = "1.27.0")]
613pub use self::eflags::*;
614
615mod fxsr;
616#[stable(feature = "simd_x86", since = "1.27.0")]
617pub use self::fxsr::*;
618
619mod bswap;
620#[stable(feature = "simd_x86", since = "1.27.0")]
621pub use self::bswap::*;
622
623mod rdtsc;
624#[stable(feature = "simd_x86", since = "1.27.0")]
625pub use self::rdtsc::*;
626
627mod cpuid;
628#[stable(feature = "simd_x86", since = "1.27.0")]
629pub use self::cpuid::*;
630mod xsave;
631#[stable(feature = "simd_x86", since = "1.27.0")]
632pub use self::xsave::*;
633
634mod sse;
635#[stable(feature = "simd_x86", since = "1.27.0")]
636pub use self::sse::*;
637mod sse2;
638#[stable(feature = "simd_x86", since = "1.27.0")]
639pub use self::sse2::*;
640mod sse3;
641#[stable(feature = "simd_x86", since = "1.27.0")]
642pub use self::sse3::*;
643mod ssse3;
644#[stable(feature = "simd_x86", since = "1.27.0")]
645pub use self::ssse3::*;
646mod sse41;
647#[stable(feature = "simd_x86", since = "1.27.0")]
648pub use self::sse41::*;
649mod sse42;
650#[stable(feature = "simd_x86", since = "1.27.0")]
651pub use self::sse42::*;
652mod avx;
653#[stable(feature = "simd_x86", since = "1.27.0")]
654pub use self::avx::*;
655mod avx2;
656#[stable(feature = "simd_x86", since = "1.27.0")]
657pub use self::avx2::*;
658mod fma;
659#[stable(feature = "simd_x86", since = "1.27.0")]
660pub use self::fma::*;
661
662mod abm;
663#[stable(feature = "simd_x86", since = "1.27.0")]
664pub use self::abm::*;
665mod bmi1;
666#[stable(feature = "simd_x86", since = "1.27.0")]
667pub use self::bmi1::*;
668
669mod bmi2;
670#[stable(feature = "simd_x86", since = "1.27.0")]
671pub use self::bmi2::*;
672
673mod sse4a;
674#[stable(feature = "simd_x86", since = "1.27.0")]
675pub use self::sse4a::*;
676
677mod tbm;
678#[stable(feature = "simd_x86", since = "1.27.0")]
679pub use self::tbm::*;
680
681mod pclmulqdq;
682#[stable(feature = "simd_x86", since = "1.27.0")]
683pub use self::pclmulqdq::*;
684
685mod aes;
686#[stable(feature = "simd_x86", since = "1.27.0")]
687pub use self::aes::*;
688
689mod rdrand;
690#[stable(feature = "simd_x86", since = "1.27.0")]
691pub use self::rdrand::*;
692
693mod sha;
694#[stable(feature = "simd_x86", since = "1.27.0")]
695pub use self::sha::*;
696
697mod adx;
698#[stable(feature = "simd_x86_adx", since = "1.33.0")]
699pub use self::adx::*;
700
701mod clflushopt;
702#[unstable(feature = "simd_x86_clflushopt", issue = "157096")]
703pub use self::clflushopt::*;
704
705#[cfg(test)]
706use stdarch_test::assert_instr;
707
708mod avx512f;
709#[stable(feature = "stdarch_x86_avx512", since = "1.89")]
710pub use self::avx512f::*;
711
712mod avx512bw;
713#[stable(feature = "stdarch_x86_avx512", since = "1.89")]
714pub use self::avx512bw::*;
715
716mod avx512cd;
717#[stable(feature = "stdarch_x86_avx512", since = "1.89")]
718pub use self::avx512cd::*;
719
720mod avx512dq;
721#[stable(feature = "stdarch_x86_avx512", since = "1.89")]
722pub use self::avx512dq::*;
723
724mod avx512ifma;
725#[stable(feature = "stdarch_x86_avx512", since = "1.89")]
726pub use self::avx512ifma::*;
727
728mod avx512vbmi;
729#[stable(feature = "stdarch_x86_avx512", since = "1.89")]
730pub use self::avx512vbmi::*;
731
732mod avx512vbmi2;
733#[stable(feature = "stdarch_x86_avx512", since = "1.89")]
734pub use self::avx512vbmi2::*;
735
736mod avx512vnni;
737#[stable(feature = "stdarch_x86_avx512", since = "1.89")]
738pub use self::avx512vnni::*;
739
740mod avx512bitalg;
741#[stable(feature = "stdarch_x86_avx512", since = "1.89")]
742pub use self::avx512bitalg::*;
743
744mod gfni;
745#[stable(feature = "stdarch_x86_avx512", since = "1.89")]
746pub use self::gfni::*;
747
748mod avx512vpopcntdq;
749#[stable(feature = "stdarch_x86_avx512", since = "1.89")]
750pub use self::avx512vpopcntdq::*;
751
752mod vaes;
753#[stable(feature = "stdarch_x86_avx512", since = "1.89")]
754pub use self::vaes::*;
755
756mod vpclmulqdq;
757#[stable(feature = "stdarch_x86_avx512", since = "1.89")]
758pub use self::vpclmulqdq::*;
759
760mod bt;
761#[stable(feature = "simd_x86_bittest", since = "1.55.0")]
762pub use self::bt::*;
763
764mod rtm;
765#[unstable(feature = "stdarch_x86_rtm", issue = "111138")]
766pub use self::rtm::*;
767
768mod f16c;
769#[stable(feature = "x86_f16c_intrinsics", since = "1.68.0")]
770pub use self::f16c::*;
771
772mod avx512bf16;
773#[stable(feature = "stdarch_x86_avx512", since = "1.89")]
774pub use self::avx512bf16::*;
775
776mod avxneconvert;
777#[stable(feature = "stdarch_x86_avx512", since = "1.89")]
778pub use self::avxneconvert::*;
779
780mod avx512fp16;
781#[stable(feature = "stdarch_x86_avx512fp16", since = "1.94.0")]
782pub use self::avx512fp16::*;
783
784mod kl;
785#[stable(feature = "keylocker_x86", since = "1.89.0")]
786pub use self::kl::*;
787
788mod movrs;
789#[unstable(feature = "movrs_target_feature", issue = "137976")]
790pub use self::movrs::*;
791
792mod avx512vp2intersect;
793#[unstable(feature = "stdarch_x86_avx512vp2intersect", issue = "111137")]
794pub use self::avx512vp2intersect::*;